﻿using Infrastructure.Attribute;
using Org.BouncyCastle.Ocsp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using ZR.Model;
using ZR.Model.Enums;
using ZR.Service.IService;
using ZR.ServiceCore.Attributes;

namespace ZR.Admin.WebApi.Services
{
    [AppService(ServiceType = typeof(ICodeModuleInfoService), ServiceLifetime = LifeTime.Scoped)]
    public class CodeModuleInfoService: ICodeModuleInfoService
    {
        /// <summary>
        /// 主模块类名后缀
        /// </summary>
        private static readonly string MainModuleClassNameSuffix = "Module";

        /// <summary>
        /// 子模块类名后缀
        /// </summary>
        private static readonly string SubModuleClassNameSuffix = "Controller";

        private readonly ILogger _logger;

        public List<CodeModuleTreeNodeInfo> CodeModuleInfos { get; private set; }

        public CodeModuleInfoService(ILogger<CodeModuleInfoService> logger) 
        {
            this._logger = logger;
            this.CodeModuleInfos = InitCodeModuleList();
        }

        private List<CodeModuleTreeNodeInfo> InitCodeModuleList()
        {
            List<CodeModuleTreeNodeInfo> list = new List<CodeModuleTreeNodeInfo>();
            try
            {
                var moduleInfoAttr = typeof(ModuleInfoAttribute);
                var relTypes = typeof(CodeModuleInfoService).Assembly.GetExportedTypes().Where(m => m.GetCustomAttributes(moduleInfoAttr, false).Length > 0);
                if (relTypes.Count() <= 0)
                {
                    return list;
                }
                foreach (var type in relTypes)
                {
                    var attrs = type.GetCustomAttributes<ModuleInfoAttribute>();
                    foreach (var attr in attrs)
                    {
                        var paModuleType = attr.PaModuleType;
                        string paModuleCode = null;
                        string moduleCode = null;
                        //当前模块为主模块，则通过类型名获取
                        if (paModuleType == null)
                        {
                            if (!type.Name.EndsWith(MainModuleClassNameSuffix))
                            {
                                continue;
                            }
                            moduleCode = type.Name.Substring(0, type.Name.Length - MainModuleClassNameSuffix.Length).FirstLowerCase();
                        }
                        //子模块
                        else
                        {
                            if (!paModuleType.Name.EndsWith(MainModuleClassNameSuffix))
                            {
                                continue;
                            }
                            paModuleCode = paModuleType.Name.Substring(0, paModuleType.Name.Length - MainModuleClassNameSuffix.Length).FirstLowerCase();
                            //指定了模块编码，则直接使用，否则从类型名获取
                            if (!string.IsNullOrWhiteSpace(attr.ModuleCode))
                            {
                                moduleCode = attr.ModuleCode;
                            }
                            else
                            {
                                if (!type.Name.EndsWith(SubModuleClassNameSuffix))
                                {
                                    continue;
                                }
                                moduleCode = type.Name.Substring(0, type.Name.Length - SubModuleClassNameSuffix.Length).FirstLowerCase();
                            }
                        }
                        var pagePath = $"{((paModuleCode?.Trim()?.Length > 0 && paModuleCode[0] != '/') ? "/" : "")}{paModuleCode}{((moduleCode?.Trim()?.Length > 0 && moduleCode[0] != '/') ? "/" : "")}{moduleCode}/index";
                        list.Add(new CodeModuleTreeNodeInfo
                        {
                            PaId = paModuleCode,
                            Id = moduleCode,
                            Label = attr.ModuleName,
                            Type=(string.IsNullOrWhiteSpace(paModuleCode)?MenuTypeEnum.Catalog:MenuTypeEnum.Page).ToEnumCode(),
                            PagePath = pagePath
                        });
                    }
                }
            }
            catch (Exception ex)
            {
                this._logger.LogError($"初始化代码模块信息异常，{ex}");
            }
            return list;
        }
    }


}
